<template>
  <el-upload :accept="fileType.join(',')"
             :action="serverUpload ? uploadUrl : uploadData.actionUrl"
             :before-upload="beforeUpload"
             :data="serverUpload ? {} : uploadData.requestData"
             :disabled="disabled || percentageShow"
             :drag="true"
             :headers="serverUpload ? uploadHeaders : {}"
             :multiple="false"
             :name="fileName"
             :on-error="handleUploadError"
             :on-progress="handleUploadProgress"
             :on-success="handleUploadSuccess"
             :show-file-list="false">
    <!-- 上传进度 -->
    <el-progress v-if="percentageShow" :color="percentageColors" :percentage="percentage" type="circle"/>
    <!-- 操作区域 -->
    <template v-else>
      <el-icon class="el-icon--upload">
        <upload-filled/>
      </el-icon>
      <div class="el-upload__text">点击按钮选择上传的文件，或拖拽文件到此区域</div>
      <div class="el-upload__tip">只能上传 {{ fileType.join(' / ') }} 文件，且不超过 {{ fileSize }}MB</div>
    </template>
  </el-upload>
</template>

<script lang="ts" setup>
import { UploadFilled } from '@element-plus/icons-vue';
import { computed, PropType, ref, watchEffect } from 'vue';
import { getRequestUrl } from '@/utils/axios/axios-service.ts';
import { getToken, getTokenHeader } from '@/utils/auth.ts';
import useUpload from '@/components/upload/src/use-upload.ts';
import { UploadProps, UploadRawFile } from 'element-plus';
import { UploadFile } from 'element-plus/es/components/upload/src/upload';

defineOptions({name: 'UploadFile'})

const props = defineProps({
  modelValue: {
    type: String,
  },
  // 是否禁用上传组件
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否显示提示信息
  showTip: {
    type: Boolean,
    default: true
  },
  // 大小限制(MB)
  fileSize: {
    type: Number,
    default: 512
  },
  // 文件类型
  fileType: {
    type: Array as PropType<string[]>,
    default: () => ['.plist', '.ipa', '.apk']
  },
  // 是否显示删除按钮
  showDelete: {
    type: Boolean,
    default: false
  },
  fileName: {
    type: String,
    default: 'file'
  },
  // 是否服务端上传
  serverUpload: {
    type: Boolean,
    default: false
  },
  // 图标保存到七牛云的路径
  uploadPath: {
    type: String,
    default: 'uploads'
  },
  // 是否重命名图片名称
  rename: {
    type: Boolean,
    default: true
  },
})
// 服务端上传地址
const uploadUrl = ref(getRequestUrl('/sys/oss/upload'));
// 服务端上传头部
const uploadHeaders = computed(() => {
  let headers = {};
  let header = getTokenHeader();
  if (header) {
    headers[header] = getToken();
  }
  return headers;
});

const emit = defineEmits(['update:modelValue', 'appInfo', 'fileInfo']);

const {
  uploadData, uploadOptions, percentage, percentageShow, percentageColors,
  beforeFileUpload, handleUploadSuccess, handleUploadError, handleUploadProgress
} = useUpload([], (url: string, file?: UploadFile) => {
  // 上传成功回调
  emit('update:modelValue', url);
  if (file) {
    emit('fileInfo', file);
  }
});

// watchEffect监听
watchEffect(() => {
  uploadOptions.limit = 1;
  uploadOptions.fileSize = props.fileSize;
  uploadOptions.fileTypes = props.fileType;
  uploadOptions.uploadPath = props.uploadPath;
  uploadOptions.rename = props.rename;
  uploadOptions.serverUpload = props.serverUpload;
});

// 文件上传之前判断
const beforeUpload: UploadProps['beforeUpload'] = (file: UploadRawFile) => {
  return beforeFileUpload(file, (result: any, extension: string) => {
    emit('appInfo', result, extension);
  });
};

</script>

<style lang="scss" scoped>
:deep(.el-upload) {
  --el-upload-dragger-padding-horizontal: 20px;
  --el-upload-dragger-padding-vertical: 10px;
  line-height: initial !important;

  .el-icon--upload {
    font-size: 56px;
    color: var(--el-text-color-placeholder);
    margin-bottom: 13px;
    line-height: 50px;
  }
}
</style>
